#include "Game.h"

#include "com_ptr.h"
#include <InitGuid.h>
#include <dxgi.h>
#include "Renderer.h"
#include "Texture.h"

#include "Polygon.h"
#include "MapBuilder.h"
#include "TextureCache.h"

Game::Game(const std::string& title, bool windowed, int width, int height)
	: m_Window("foobar", width, height), m_Renderer("resource/pixelshader.txt", "resource/vertexshader.txt"), 
	m_Display(m_Renderer.GetDevice(), m_Window.GetHandle(), width, height, true), 
	m_Device(m_Renderer.GetDevice()), m_Context(m_Renderer.GetDeviceContext())
	//m_Device (width, height, windowed, m_Window.GetHandle()), renderobj(m_Device.GetDevice(), m_Device.GetContext())
{
	Setup(width, height);
}

void Game::Setup(int width, int height)
{
	D3D11_VIEWPORT viewport;
	viewport.TopLeftX = 0;
	viewport.TopLeftY = 0;
	viewport.Width = width;
	viewport.Height = height;
	viewport.MaxDepth = 1.0f;
	viewport.MinDepth = 0.0f;
	
	m_Context->RSSetViewports (1, &viewport);

	D3D11_SAMPLER_DESC samplerDesc;
	samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
	samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerDesc.MipLODBias = 0.0f;
	samplerDesc.MaxAnisotropy = 1;
	samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
	samplerDesc.BorderColor[0] = 0;
	samplerDesc.BorderColor[1] = 0;
	samplerDesc.BorderColor[2] = 0;
	samplerDesc.BorderColor[3] = 0;
	samplerDesc.MinLOD = 0;
	samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;

	ID3D11SamplerState* sampleState;
	HRESULT result = m_Device->CreateSamplerState(&samplerDesc, &sampleState);
	if(FAILED(result))
	{
		throw std::runtime_error("Can't create sampler state");
	}

	ID3D11SamplerState* samplers[] = {sampleState};
	m_Context->PSSetSamplers(0, 1, samplers);

	D3D11_RASTERIZER_DESC rsDesc;
	rsDesc.FillMode = D3D11_FILL_SOLID;
	rsDesc.CullMode = D3D11_CULL_NONE;
	rsDesc.FrontCounterClockwise = FALSE;
	rsDesc.DepthBias = 0;
	rsDesc.DepthBiasClamp = 0.0f;
	rsDesc.SlopeScaledDepthBias = 0.0f;
	rsDesc.DepthClipEnable = FALSE; 
	rsDesc.ScissorEnable = FALSE;
	rsDesc.MultisampleEnable = FALSE;
	rsDesc.AntialiasedLineEnable = FALSE;

	ID3D11RasterizerState* rasterizerState;
	result = m_Device->CreateRasterizerState(&rsDesc, &rasterizerState);
	if(FAILED(result))
	{
		throw std::runtime_error("Can't create rasterizer state");
	}

	m_Context->RSSetState(rasterizerState);

	ID3D11RenderTargetView* render_target_views[] = {m_Display.GetRenderTargetView()};
	m_Context->OMSetRenderTargets(1, render_target_views, nullptr);
}

bool Game::Run()
{
	MSG Msg;
	bool bRun = true;
	::DWORD frameticks = GetTickCount();
	
	float frametime = 0.0f;
	int fps = 0;
	float frametime_counter = 0.0f;

	MapBuilder builder("resource/test.xml");

	m_Renderer.PreloadTextureList(builder.GetTexturePathes());

	while(bRun)
	{
		frameticks = GetTickCount();
		while(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&Msg);
			DispatchMessage(&Msg);
			if(Msg.message == WM_QUIT)
			{
				bRun = false;
			}
			
			FLOAT color[4] = {1.0f, 0.0f, 0.0f, 1.0f};
			m_Display.ClearScreen(color);

			std::list<ftb::Polygon> polygons = builder.GetPolygons();
			{
				Renderer::SpriteBatch spritebatch(m_Renderer);

				for(auto it = polygons.begin();
					it != polygons.end();
					++it)
				{
					it->Render(m_Renderer);
				}		
			}
			m_Display.Present();
		}

		

	}
	return true;
}
